package com.maiko.maikoaiagent.agent;

import cn.hutool.core.util.StrUtil;
import com.maiko.maikoaiagent.agent.model.AgentState;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;

import java.util.ArrayList;
import java.util.List;

/**
 * BaseAgent 是一个抽象智能代理基类，具备多轮对话上下文、状态控制、步骤执行机制。
 * 子类需实现 step() 方法定义具体任务流程。
 * 典型用途包括任务分解、自动流程控制、多轮对话等智能 Agent 场景。
 * @author: Maiko7
 * @create: 2025-07-10 7:51
 */
@Data
@Slf4j
public abstract class BaseAgent {

    // ==================== 基础属性 ====================

    /** 代理名称（可用于日志输出或区分多个代理） */
    private String name;

    /** 系统提示词：用于初始化时对大模型的背景设定 */
    private String systemPrompt;

    /** 下一步提示词：用于控制每一步提示内容 */
    private String nextStepPrompt;

    /** 代理当前状态（空闲、运行中、已完成、出错等） */
    private AgentState state = AgentState.IDLE;

    // ==================== 执行控制 ====================

    /** 允许执行的最大步骤数，防止死循环 */
    private int maxSteps = 10;

    /** 当前执行到的步骤编号 */
    private int currentStep = 0;

    // ==================== LLM 与记忆 ====================

    /** 用于与大语言模型交互的客户端实例 */
    private ChatClient chatClient;

    /** 消息上下文列表，存储用户和模型的历史消息，实现对话记忆 */
    private List<Message> messageList = new ArrayList<>();

    // ==================== 主执行逻辑 ====================

    /**
     * 启动代理并执行多步任务
     *
     * @param userPrompt 用户输入的初始提示词
     * @return 执行过程中的每一步结果组成的字符串
     */
    public String run(String userPrompt) {
        // 状态检查
        if (this.state != AgentState.IDLE) {
            throw new RuntimeException("Cannot run agent from state: " + this.state);
        }
        if (StrUtil.isBlank(userPrompt)) {
            throw new RuntimeException("Cannot run agent with empty user prompt");
        }

        // 设置运行状态
        state = AgentState.RUNNING;

        // 初始化对话上下文
        messageList.add(new UserMessage(userPrompt));

        // 执行结果集合
        List<String> results = new ArrayList<>();

        try {
            // 循环执行步骤
            for (int i = 0; i < maxSteps && state != AgentState.FINISHED; i++) {
                int stepNumber = i + 1;
                currentStep = stepNumber;
                log.info("Executing step " + stepNumber + "/" + maxSteps);

                // 单步执行逻辑（由子类实现）
                String stepResult = step();
                String result = "Step " + stepNumber + ": " + stepResult;
                results.add(result);
            }

            // 超出最大步骤，强制终止
            if (currentStep >= maxSteps) {
                state = AgentState.FINISHED;
                results.add("Terminated: Reached max steps (" + maxSteps + ")");
            }

            // 返回所有步骤结果
            return String.join("\n", results);

        } catch (Exception e) {
            // 异常处理，设置为错误状态
            state = AgentState.ERROR;
            log.error("Error executing agent", e);
            return "执行错误：" + e.getMessage();
        } finally {
            // 清理资源（可选）
            this.cleanup();
        }
    }

    /**
     * 抽象方法：执行单个步骤的逻辑
     * 子类必须实现该方法来定义每一步的行为
     *
     * @return 当前步骤的执行结果字符串
     */
    public abstract String step();

    /**
     * 清理资源，例如释放缓存、日志收尾等
     * 子类可以重写此方法来定制清理逻辑
     */
    protected void cleanup() {
        // 默认无操作，子类可按需实现
    }
}


